﻿﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using DigibizTree.Picker;
using umbraco.cms.businesslogic.media;
using System.Text;
using umbraco.IO;
using System.Web.UI.HtmlControls;
using umbraco.interfaces;
using umbraco.cms.businesslogic.datatype.controls;
using umbraco.cms.businesslogic.propertytype;
using System.Xml;
using umbraco.cms.businesslogic.property;
using umbraco.DataLayer;
using System.Xml.XPath;
using System.Xml.Linq;
using umbraco;
using DigibizTree;

namespace DigibizAdvancedMediaPicker
{
    public partial class CreateMediaItem : umbraco.BasePages.BasePage
    {
        public DigibizPickerView digibizPickerView;
        public IDataType uploadField = new Factory().GetNewObject(new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c"));

        /// <summary>
        /// Return the client id of the HtmlInputFile which is part of the upload field.
        /// </summary>
        public string UploadFieldClientId
        {
            get
            {
                return ((HtmlInputFile)uploadField.DataEditor).ClientID;
            }
        }

        /// <summary>
        /// If no allowed extensions are selected return false and don't render the javascript.
        /// </summary>
        public bool RenderAllowedExtensionCheck
        {
            get
            {
                string allowedExtensions = Request.QueryString["allowedExtensions"].ToLower();

                return (!string.IsNullOrEmpty(allowedExtensions)) && (allowedExtensions != DigibizConstants.ALLEXTENSIONS);
            }
        }

        private string _cropPropertyAlias;
        private string _cropName;

        protected override void OnInit(EventArgs e)
        {
            try
            {
                base.OnInit(e);

                int startNodeId = -1;
                int.TryParse(Request.QueryString["startNodeId"], out startNodeId);

                string allowedExtensions = Request.QueryString["allowedExtensions"];
                _cropPropertyAlias = Request.QueryString["cropPropertyAlias"];
                _cropName = Request.QueryString["cropName"];

                //Add the onchange event which is used to update the name textbox when a file is selected.
                HtmlInputFile htmlUploadField = (HtmlInputFile)uploadField.DataEditor;
                htmlUploadField.Attributes.Add("onchange", "javascript:SetFileName();");

                //Create the DigibizPickerView (the tree to select a folder) and add it to the placeholder.
                digibizPickerView = new DigibizPickerView();
                digibizPickerView.StartNodeId = startNodeId;
                digibizPickerView.AllowedExtensions = string.Empty;
                digibizPickerView.IsCreateTree = true;
                digibizPickerView.SelectStartNode = true;
                digibizPickerView.PickerClass = "DigibizPickerSmall clearfix";
                digibizPickerView.CropPropertyAlias = _cropPropertyAlias;
                digibizPickerView.CropName = _cropName;
                PlaceholderPicker.Controls.Add(digibizPickerView);

                //Add the upload field to the placeholder.
                PlaceHolderUpload.Controls.Add((Control)uploadField.DataEditor);
            }
            catch (Exception ex)
            {
                DAMP_Helper.LogException(ex);
                ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "ErrorInit", DigibizConstants.DEFAULTERRORALERT, true);
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                ((HtmlInputFile)uploadField.DataEditor).ID = "UploadField";

                if (!IsPostBack)
                {
                    DdlMediaTypes.Items.Clear();
                    DdlMediaTypes.Items.Add(new ListItem("Choose Media Type", "-1"));
                    DdlMediaTypes.AppendDataBoundItems = true;
                    DdlMediaTypes.DataSource = string.IsNullOrEmpty(GetAllowedMediaTypes()) ? MediaType.GetAllAsList() : MediaType.GetAllAsList().Where(x => GetAllowedMediaTypes().IndexOf("," + x.Id + ",") > -1);
                    DdlMediaTypes.DataTextField = "Text";
                    DdlMediaTypes.DataValueField = "Id";
                    DdlMediaTypes.DataBind();

                    SetDefaultMediaType(DdlMediaTypes);
                }
            }
            catch (Exception ex)
            {
                DAMP_Helper.LogException(ex);
                ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "ErrorLoad", DigibizConstants.DEFAULTERRORALERT, true);
            }
        }

        protected void BtnCreate_Click(object sender, EventArgs e)
        {
            try
            {
                //Get the selected media type.
                MediaType mediaType = new MediaType(Convert.ToInt32(DdlMediaTypes.SelectedValue));

                umbraco.BusinessLogic.User user = umbraco.BusinessLogic.User.GetCurrent();

                if (user == null)
                {
                    //If no user is found use the admin.
                    user = new umbraco.BusinessLogic.User(0);
                }

                //Create the new media item.
                Media newMedia = Media.MakeNew(TxtName.Text, mediaType, user, Convert.ToInt32(digibizPickerView.PickedValue.Value));

                if (Convert.ToBoolean(HiddenFieldHasUploadFile.Value))
                {
                    string alias = string.Empty;

                    //Get the propertyid and datatypeid and set them on the upload field. Now the upload field will automatically do the upload to the newly created media item.
                    string sql = string.Format(@"
                        select cpd.id as id, cpt.dataTypeId as datatypeid, cpt.Alias as alias  from cmsPropertyData cpd
                            inner join cmsPropertyType cpt on cpd.propertytypeid = cpt.Id
                            inner join cmsDataType cdt on cpt.dataTypeId = cdt.nodeId
                        where cpd.contentNodeId = {0}
                        and cdt.controlId = '{1}'", newMedia.Id, uploadField.Id);

                    using (IRecordsReader dr = SqlHelper.ExecuteReader(sql))
                    {
                        while (dr.Read())
                        {
                            //Set the values of the first upload datatype that was found on the media type.
                            uploadField.Data.PropertyId = dr.GetInt("id");
                            uploadField.DataTypeDefinitionId = dr.GetInt("datatypeid");
                            alias = dr.GetString("alias");

                            //We only need the first result. If other upload fields are found we don't need them.
                            break;
                        }
                    }

                    //Upload the file and set all the related properties.
                    uploadField.DataEditor.Save();

                    if (umbraco.GlobalSettings.VersionMajor > 4)
                    {
                        //Set the value on the media object so it will be part of the transaction in v6 or higher.
                        newMedia.getProperty(alias).Value = uploadField.Data.Value;
                    }
                }

                //Call the save method to update the media xml.
                //This way also the BeforeSave and AfterSave events will be called so they can be used.
                newMedia.Save();
                newMedia.XmlGenerate(new XmlDocument());

                //Get the newly created media item from the umbraco cache.
                XPathNodeIterator mediaIterator = library.GetMedia(newMedia.Id, false);

                //Convert the XPathNodeIterator to an XDocument.
                XDocument xmlDocument = XDocument.Parse(mediaIterator.Current.OuterXml);

                //Get the root element.
                XElement mediaElement = xmlDocument.Root;

                //Display the name of the new media item.
                LitName.Text = DigibizMediaHelper.GetMediaName(mediaElement);

                //Set the link to the new media item.
                string link = DigibizMediaHelper.GetMediaLink(mediaElement);
                if ((!string.IsNullOrEmpty(link)) && link != "#")
                {
                    //Only set the link if it's a real link.
                    HplNewMediaItem.NavigateUrl = link;
                }

                //Display the icon/image of the newly created media item.  Show the cropped image if it's available (called automatically by DAMP_Helper)
                ltlNewMediaImage.Text = DigibizMediaHelper.ShowImage(
                    DigibizMediaHelper.GetMediaLink(mediaElement),
                    DigibizConstants.IMAGEPREVIEWWIDTH_CREATE,
                    DigibizConstants.IMAGEPREVIEWHEIGHT_CREATE,
                    DigibizMediaHelper.GetMediaId(mediaElement),
                    crop: DigibizMediaHelper.GetMediaCrop(mediaElement, _cropPropertyAlias, _cropName),
                    icon: DigibizMediaHelper.GetMediaIcon(mediaElement));

                string allowedSelectableMediaTypes = GetAllowedSelectableMediaTypes();

                if (string.IsNullOrEmpty(allowedSelectableMediaTypes) || allowedSelectableMediaTypes.Contains(mediaType.Id.ToString()))
                {
                    //Register the function to select the created id.
                    ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "Select", "function GetNodeId(){UmbClientMgr.closeModalWindow('" + newMedia.Id + "');}", true);

                    PlaceHolderSelect.Visible = true;
                    LblMessage.Text = "<strong>Select</strong> this media item or <strong>create</strong> another one.";
                    LblMessage.Style.Clear();
                }
                else
                {
                    PlaceHolderSelect.Visible = false;
                    LblMessage.Text = "The created media item is not allowed to be selected. <strong>Create</strong> another one or <strong>cancel.</strong>";
                    LblMessage.Style.Add("color", "red");
                }

                //Display the view the upload was a succes.
                MultiViewPage.SetActiveView(ViewSucces);
            }
            catch (Exception ex)
            {
                DAMP_Helper.LogException(ex);
                ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "ErrorCreate", DigibizConstants.DEFAULTERRORALERT, true);
            }
        }

        protected void BtnCreateAgain_Click(object sender, EventArgs e)
        {
            try
            {
                //Reset the selected values.
                DdlMediaTypes.SelectedIndex = 0;
                PropFile.Visible = true;
                TxtName.Text = string.Empty;
                digibizPickerView.PickedValue.Value = string.Empty;

                //Display the create view again because the user wants to create another media item.
                MultiViewPage.SetActiveView(ViewCreate);

                //Repick the default media type
                SetDefaultMediaType(DdlMediaTypes);
            }
            catch (Exception ex)
            {
                DAMP_Helper.LogException(ex);
                ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "ErrorCreateAgain", DigibizConstants.DEFAULTERRORALERT, true);
            }
        }

        /// <summary>
        /// Get the allowed extensions from the querystring and return it in the required format.
        /// </summary>
        /// <returns></returns>
        public string GetAllowedExtensions()
        {
            string allowedExtensions = Request.QueryString["allowedExtensions"].Replace(" ", string.Empty).ToLower();

            if (!allowedExtensions.StartsWith(","))
            {
                allowedExtensions = "," + allowedExtensions;
            }

            if (!allowedExtensions.EndsWith(","))
            {
                allowedExtensions = allowedExtensions + ",";
            }

            return allowedExtensions;
        }

        /// <summary>
        /// Get the allowed media types from the querystring and return it in the required format.
        /// </summary>
        /// <returns></returns>
        public string GetAllowedMediaTypes()
        {
            string allowedMediaTypes = Request.QueryString["allowedMediaTypes"].Replace(" ", string.Empty).ToLower();

            if (string.IsNullOrEmpty(allowedMediaTypes))
                return string.Empty;

            if (!allowedMediaTypes.StartsWith(","))
            {
                allowedMediaTypes = "," + allowedMediaTypes;
            }

            if (!allowedMediaTypes.EndsWith(","))
            {
                allowedMediaTypes = allowedMediaTypes + ",";
            }

            return allowedMediaTypes;
        }

        /// <summary>
        /// Get the allowed selectable media types from the querystring and return it in the required format.
        /// </summary>
        /// <returns></returns>
        public string GetAllowedSelectableMediaTypes()
        {
            string allowedSelectableMediaTypes = Request.QueryString["allowedSelectableMediaTypes"].Replace(" ", string.Empty).ToLower();

            if (string.IsNullOrEmpty(allowedSelectableMediaTypes))
                return string.Empty;

            if (!allowedSelectableMediaTypes.StartsWith(","))
            {
                allowedSelectableMediaTypes = "," + allowedSelectableMediaTypes;
            }

            if (!allowedSelectableMediaTypes.EndsWith(","))
            {
                allowedSelectableMediaTypes = allowedSelectableMediaTypes + ",";
            }

            return allowedSelectableMediaTypes;
        }

        /// <summary>
        /// Format the extensions so they can be shown in an alert.
        /// </summary>
        /// <param name="extensions"></param>
        /// <returns></returns>
        public string ShowExtensions(string extensions)
        {
            if (!string.IsNullOrEmpty(extensions))
            {
                return extensions.Replace(" ", string.Empty).ToLower().TrimStart(',').TrimEnd(',').Replace(",", " | ");
            }
            return null;
        }

        /// <summary>
        /// Sets the default media type selection in the given dropdown list. Also calls EnableUploadFieldForUploadTypes to update
        /// </summary>
        /// <param name="ddl"></param>
        public void SetDefaultMediaType(DropDownList ddl)
        {
            if (ddl.Items.FindByValue(Request.QueryString["defaultMediaType"]) != null)
            {
                ddl.SelectedValue = Request.QueryString["defaultMediaType"];
            }
            else if (ddl.Items.Count == 2)
            {
                // If there's only one media type go ahead and select it (?)
                ddl.Items[1].Selected = true;
            }
        }
    }
}